package com.yc.cinema.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect  // 切面类
public class MyAspect {

    // 前置增强  AspectJ切点表达式
    @Before("execution(* com..biz.*.*(..))")
    // 接口注入
    public void logger(JoinPoint joinPoint){
        final Signature signature = joinPoint.getSignature();// 业务方法签名
        System.out.println("signature = " + signature);
        final Object[] args = joinPoint.getArgs();// 参数数组
        System.out.println("args = " + args);
    }

    // 切点方法
    @Pointcut("execution(* com..biz.*.*(..))")
    public void pointcut(){}

    // 后置增强
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        System.out.println("-------after-------");
    }

    // 返回增强
    @AfterReturning(value = "pointcut()", returning = "a")
    public void afterReturning(JoinPoint joinPoint, Object a){
        // a 是业务方法的返回值
        System.out.println("-------afterReturning------- " + a);
    }

    // 异常增强
    @AfterThrowing(pointcut = "execution(* com..dao.*.*(..))", throwing = "t")
    public void afterThrowing(JoinPoint joinPoint, Throwable t){
        System.out.println("-------afterThrowing------- " + t);
    }

    /**
     * try{
     *     => 前置增强
     *     业务方法
     *     => 返回增强 (afterReturning)
     * } catch (...) {
     *     => 异常增强 (afterThrowing)
     * } finally{
     *     => 后置增强
     * }
     */

    // 错误的计算时间的方法  begin
    long time1;
    long time2;
    public void before1(){
        time1 = System.currentTimeMillis();
    }
    public void after1(){
        time2 = System.currentTimeMillis();
        long time = time2 - time1;
    }
    // 错误的计算时间的方法 end

    // 环绕增强实现性能监控
    @Around("execution(* com.yc.cinema.web.*Action.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // ProceedingJoinPoint 环绕增强专用连接点对象
        long time1 = System.currentTimeMillis();
        // 必须手动执行业务方法
        Object returning = pjp.proceed();
        long time2 = System.currentTimeMillis();
        long time = time2 - time1;
        System.out.println( pjp.getSignature() + " 共耗时: " + time + " 毫秒");
        // 必须手动返回业务方法的结果
        return returning;
    }
}

